package kit.docker.redis;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import kit.docker.convert.ConvertKit;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisKit {

    public static boolean exists(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.exists(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static boolean existsByPattern(String cacheName, String pattern) {
        Set<String> keys = getKeys(cacheName, pattern);
        if (StrKit.notNull(keys) && keys.size() > 0) {
            return true;
        }
        return false;
    }

    public static String set(String cacheName, String key, String value) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.set(key, value);
        } finally {
            cache.close(jedis);
        }
    }

    public static String set(String cacheName, String key, String value, int seconds) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.setex(key, seconds, value);
        } finally {
            cache.close(jedis);
        }
    }

    public static String get(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.get(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static void del(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            jedis.del(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static void delByPattern(String cacheName, String pattern) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            Set<String> keys = jedis.keys(pattern);
            for (String key : keys) {
                jedis.del(key);
            }
        } finally {
            cache.close(jedis);
        }
    }

    public static void del(String cacheName, Set<String> keys) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            for (String key : keys) {
                jedis.del(key);
            }
        } finally {
            cache.close(jedis);
        }
    }

    public static long ttl(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.ttl(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static Set<String> getKeys(String cacheName, String pattern) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.keys(pattern);
        } finally {
            cache.close(jedis);
        }
    }

    public static boolean hexists(String cacheName, String key, String field) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.hexists(key, field);
        } finally {
            cache.close(jedis);
        }
    }

    public static void hdel(String cacheName, String key, String... field) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            jedis.hdel(key, field);
        } finally {
            cache.close(jedis);
        }
    }

    public static String hget(String cacheName, String key, String field) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.hget(key, field);
        } finally {
            cache.close(jedis);
        }
    }

    public static Map<String, String> hgetAll(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.hgetAll(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static String hmsetStr(String cacheName, String key, Map<String, String> hash) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.hmset(key, hash);
        } finally {
            cache.close(jedis);
        }
    }

    public static String hmset(String cacheName, String key, Map<String, String> hash) {
        return hmsetStr(cacheName, key, hash);
    }

    public static String hmset(String cacheName, String key, Map<String, Object> hash, int seconds) {
        return hmsetStr(cacheName, key, ConvertKit.mapTomap(hash), seconds);
    }

    public static String hmsetStr(String cacheName, String key, Map<String, String> hash, int seconds) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            String result = jedis.hmset(key, hash);
            jedis.expire(key, seconds);
            return result;
        } finally {
            cache.close(jedis);
        }
    }

    public static void expire(String cacheName, String key, int seconds) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            jedis.expire(key, seconds);
        } finally {
            cache.close(jedis);
        }
    }

    public static void batchLPush(String cacheName, String key, List<String> values) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            Pipeline pipeline = jedis.pipelined();
            for (String value : values) {
                pipeline.lpush(key, value);
            }
            pipeline.sync();
        } finally {
            cache.close(jedis);
        }
    }

    public static Long lPush(String cacheName, String key, String... value) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.lpush(key, value);
        } finally {
            cache.close(jedis);
        }
    }

    public static Long llen(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.llen(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static List<String> brpop(String cacheName, String... key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.brpop(0, key);
        } finally {
            cache.close(jedis);
        }
    }

    public static String brpoplpush(String cacheName, String source, String destination) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.brpoplpush(source, destination, 0);
        } finally {
            cache.close(jedis);
        }
    }

    public static Long incr(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.incr(key);
        } finally {
            cache.close(jedis);
        }
    }

    public static Long decr(String cacheName, String key) {
        Cache cache = Redis.use(cacheName);
        Jedis jedis = cache.getJedis();
        try {
            return jedis.decr(key);
        } finally {
            cache.close(jedis);
        }
    }

}
